
 
#include "stdafx.h"
#include "BaseEditor.h"
#include "OgitorsRoot.h"
#include "NodeEditor.h"
#include "mirror.h"
#include "mirrorEditor.h"


using namespace Ogitors;

static CMirrorEditorFactory PlaneEditorFactory;
static mirror * m_mirror = NULL;
//-------------------------------------------------------------------------------
mirrorEditor::mirrorEditor(Ogre::String typestring, EDITORTYPE etype) : CNodeEditor(typestring, etype) ,m_plane("refe")
{
	m_PlaneHandle = 0;
	m_UsesGizmos = true;
	m_UsesHelper = false;
	m_EditFlags = CAN_MOVE | CAN_SCALE | CAN_ROTATE | CAN_CLONE | CAN_DELETE  | CAN_FOCUS | CAN_DRAG | CAN_UNDO;

	m_Normal = Ogre::Vector3::UNIT_Y;
	m_Distance = 0.0f;
	m_Width = 10.0f;;
	m_Height = 10.0f;
	m_xSegments = 1;
	m_ySegments = 1;
	m_NumCoordSets = 1;
	m_uTile = 1;
	m_vTile = 1;
	m_HasNormals = true;
//	m_CReflection = NULL;
}
mirrorEditor::~mirrorEditor() 
{
// 	if (m_CReflection)
// 	{
// 		delete m_CReflection;
// 		m_CReflection = NULL;
// 	}

	if (m_mirror)
	{		delete m_mirror;
	m_mirror = NULL;
	}
};
//-------------------------------------------------------------------------------
CBaseEditorFactory *mirrorEditor::GetFactory()
{
	return &PlaneEditorFactory;
}
//-------------------------------------------------------------------------------
CBaseEditorFactory *mirrorEditor::GetFactoryDynamic()
{
	return &PlaneEditorFactory;
}
//-------------------------------------------------------------------------------
void mirrorEditor::SetHandle(void *objHandle,bool display)
{
	if(m_PlaneHandle)
		UnRegisterObjectName();
	m_PlaneHandle = (Ogre::Entity *)objHandle;
	m_Handle = m_PlaneHandle->getParentSceneNode();
	m_Name = m_PlaneHandle->getName();
	RegisterObjectName();
	RegisterForUpdates();
	m_PlaneHandle->setQueryFlags(QUERYFLAG_MOVABLE);
	if(display) 
		SetupPropertiesWnd();
}
//-------------------------------------------------------------------------------
void mirrorEditor::FreeHandle()
{
	CBaseEditor::FreeHandle();
	if(m_PlaneHandle)
	{
		UnRegisterObjectName();
		UnRegisterForUpdates();
		m_Name = "";
		DETACHFROMPARENT(m_PlaneHandle);
		m_PlaneHandle->_getManager()->destroyEntity(m_PlaneHandle);
		m_PlaneHandle = 0;
	}
	if(m_Handle)
	{
		m_Handle->getParentSceneNode()->removeAndDestroyChild(m_Handle->getName());
		m_Handle = 0;
	}
// 	if (m_CReflection)
// 	{
// 		delete m_CReflection;
// 		m_CReflection = NULL;
// 	}
}
//-----------------------------------------------------------------------------------------
void mirrorEditor::ShowBoundingBox(bool bShow) 
{
	if(!m_BoxParentNode && m_EditorType != ETYPE_BASE)
		CreateBoundingBox();

	m_BBoxNode->setVisible(bShow);
}//-------------------------------------------------------------------------------
Ogre::Entity *mirrorEditor::CreatePlane()
{
	Ogre::MeshPtr mesh;
	Ogre::String matName = "";
	if(m_PlaneHandle)
	{
		matName = m_PlaneHandle->getSubEntity(0)->getMaterialName();
		DETACHFROMPARENT(m_PlaneHandle);
		m_PlaneHandle->_getManager()->destroyEntity(m_PlaneHandle);
		Ogre::MeshManager::getSingletonPtr()->remove(m_Name);        
	}

	//m_plane =  Ogre::MovablePlane(m_Normal, m_Distance);
	m_plane.d = 0;
	m_plane.normal = Vector3::UNIT_Y;

	mesh = Ogre::MeshManager::getSingletonPtr()->createPlane(m_Name,"ProjectResources",m_plane,m_Width,m_Height,m_xSegments,m_ySegments,m_HasNormals,m_NumCoordSets,m_uTile,m_vTile,Ogre::Vector3::UNIT_Z);


// 	mesh =MeshManager::getSingleton().createPlane(m_Name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
// 		m_plane, 7, 13, 10, 10, true, 1, 3, 5, Vector3::UNIT_Z);




	m_PlaneHandle = OgitorsRoot::getSingletonPtr()->GetSceneManager()->createEntity(m_Name, m_Name);
	m_PlaneHandle->setQueryFlags(QUERYFLAG_MOVABLE);

	if(matName != "")
		;// m_PlaneHandle->setMaterialName(matName);

	m_Handle->attachObject(m_PlaneHandle);

	//m_CReflection = new CReflection();
	//m_CReflection->init(static_cast<Ogre::Camera *>(OgitorsRoot::getSingleton().GetViewport()->GetCameraEditor()->GetHandle()),

	//&m_plane,m_PlaneHandle,"reff");

	//m_PlaneHandle->setMaterialName("ref");
	if (!m_mirror)
	{
		m_mirror = new mirror();
		m_mirror->init( OgitorsRoot::getSingleton().GetRenderWindow(),
			static_cast<Ogre::Camera *>(OgitorsRoot::getSingleton().GetViewport()->GetCameraEditor()->GetHandle()),
			&m_plane,
			m_PlaneHandle,
			m_Handle,
			OgitorsRoot::getSingleton().GetSceneManager()
			);

	}



	return m_PlaneHandle;
}

bool mirrorEditor::Update(float timePassed) 
{
	if (m_mirror)
	{ 
		m_mirror->updata();
	}
	return false;
}
//-------------------------------------------------------------------------------
void mirrorEditor::SetCastShadows(int BIND_ID,Ogre::String val,bool refresh)
{
	bool iVal = Ogre::StringConverter::parseBool(val);
	m_PlaneHandle->setCastShadows(iVal);
	if(refresh)
	{
		m_System->SetProperty(this,BIND_ID,iVal);
	}
	SetModified(true);
}
//-------------------------------------------------------------------------------
bool mirrorEditor::SetupPropertiesWnd()
{
	if(!CNodeEditor::SetupPropertiesWnd()) 
		return false;

	m_System->SetProperty(this,BIND_CASTSHADOWS,m_PlaneHandle->getCastShadows());

	m_System->SetProperty(this,CUSTOM_BINDING_START + 1, m_Normal.x);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 2, m_Normal.y);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 3, m_Normal.z);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 4, m_Distance);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 5, m_Width);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 6, m_Height);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 7, m_xSegments);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 8, m_ySegments);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 9, m_NumCoordSets);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 10, m_uTile);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 11, m_vTile);
	m_System->SetProperty(this,CUSTOM_BINDING_START + 12, m_HasNormals);

	Ogre::StringVector MaterialNames;
	Ogre::MaterialManager::ResourceMapIterator it = Ogre::MaterialManager::getSingleton().getResourceIterator();
	while(it.hasMoreElements())
	{
		Ogre::ResourcePtr mRes = it.getNext();
		if(mRes->getGroup() == "ProjectResources")
			MaterialNames.push_back(mRes->getName());
	}
	std::sort(MaterialNames.begin(),MaterialNames.end());

	m_System->FillPropertyOptions(this,CUSTOM_BINDING_START + 13, MaterialNames);
	Ogre::String matname = m_PlaneHandle->getSubEntity(0)->getMaterialName();
	m_System->SetProperty(this,CUSTOM_BINDING_START + 13, matname);

	return true;
}


// <mirror name="Entity11" height="10" width="10" BlockTexture = "dfd.dds">
// <position x="0"  y="0"  z="0"/>
// <rotation x="0"  y="0"  z="0"  w="-1"/>
// <scale x="1"  y="1"  z="1"/>
// </mirror >
#include "publicFunc.h"

void		mirrorEditor::GetObjectUserData(std::ofstream &outfile)
{

	Vector3    pos = GetPosition();
	Quaternion qua = GetOrientation();
	Vector3    sca = GetScale();

	outfile << "<mirror name= " <<"\"" << GetName() <<"\"" 
		<<Pub::getatt("height", Ogre::StringConverter::toString(m_Width))
		<<Pub::getatt("width", Ogre::StringConverter::toString(m_Height))
		<<Pub::getatt("BlockTexture", m_BlockTexture)

		<<">\n";
		//<<  " height= " <<"\"" <<m_ParticleSystem<<"\"" << ">\n";

	outfile<<"<position x=" <<"\"" <<pos.x <<"\""
		<<" y="<<"\"" <<pos.y<<"\"" 
		<<" z="<<"\"" <<pos.z<<"\""<<"/>\n";

	outfile<<"<rotation x=" <<"\"" <<qua.x <<"\""
		<<" y="<<"\"" <<qua.y<<"\"" 
		<<" z="<<"\"" <<qua.z<<"\""
		<<" w="<<"\"" <<qua.w<<"\""<<"/>\n";

	outfile<<"<scale x=" <<"\"" <<sca.x <<"\""
		<<" y="<<"\"" <<sca.y<<"\"" 
		<<" z="<<"\"" <<sca.z<<"\""<<"/>\n";


}

//-------------------------------------------------------------------------------
void mirrorEditor::GetObjectProperties(Ogre::NameValuePairList &retList)
{
	retList.clear();
	CNodeEditor::GetObjectProperties(retList);
	retList["shadows"] = Ogre::StringConverter::toString(m_PlaneHandle->getCastShadows());
	retList["normal"] = Ogre::StringConverter::toString(m_Normal);
	retList["distance"] = Ogre::StringConverter::toString(m_Distance);
	retList["width"] = Ogre::StringConverter::toString(m_Width);
	retList["height"] = Ogre::StringConverter::toString(m_Height);
	retList["xsegments"] = Ogre::StringConverter::toString(m_xSegments);
	retList["ysegments"] = Ogre::StringConverter::toString(m_ySegments);
	retList["numcoordsets"] = Ogre::StringConverter::toString(m_NumCoordSets);
	retList["utile"] = Ogre::StringConverter::toString(m_uTile);
	retList["vtile"] = Ogre::StringConverter::toString(m_vTile);
	retList["hasnormals"] = Ogre::StringConverter::toString(m_HasNormals);
	retList["material"] = m_PlaneHandle->getSubEntity(0)->getMaterialName();
}
//-------------------------------------------------------------------------------
bool mirrorEditor::HandleCustomFunction(int BIND_ID,Ogre::String val)
{
	switch(BIND_ID)
	{
	case 1:
	case 2:
	case 3:{
		m_Normal.x = m_System->GetFloatProperty(this,CUSTOM_BINDING_START + 1);
		m_Normal.y = m_System->GetFloatProperty(this,CUSTOM_BINDING_START + 2);
		m_Normal.z = m_System->GetFloatProperty(this,CUSTOM_BINDING_START + 3);
		m_Normal.normalise();
		CreatePlane();
		break;
		   }
	case 4:m_Distance = Ogre::StringConverter::parseReal(val);CreatePlane();break;
	case 5:m_Width = Ogre::StringConverter::parseReal(val);CreatePlane();break;
	case 6:m_Height = Ogre::StringConverter::parseReal(val);CreatePlane();break;
	case 7:m_xSegments = Ogre::StringConverter::parseInt(val);CreatePlane();break;
	case 8:m_ySegments = Ogre::StringConverter::parseInt(val);CreatePlane();break;
	case 9:m_NumCoordSets = Ogre::StringConverter::parseInt(val);CreatePlane();break;
	case 10:m_uTile = Ogre::StringConverter::parseInt(val);CreatePlane();break;
	case 11:m_vTile = Ogre::StringConverter::parseInt(val);CreatePlane();break;
	case 12:m_HasNormals = (Ogre::StringConverter::parseInt(val) != 0);CreatePlane();break;
		//case 13:m_PlaneHandle->setMaterialName(val);break;
	}

	return true;
}
//-------------------------------------------------------------------------------
CBaseEditor *mirrorEditor::Restore(Ogre::NameValuePairList &retList)
{
	Ogre::NameValuePairList theList;
	GetObjectProperties(theList);
	Ogre::NameValuePairList::const_iterator ni;

	mirrorEditor *object = static_cast<mirrorEditor*>(CNodeEditor::Restore(retList));

	if ((ni = retList.find("normal")) != retList.end())
	{
		object->m_Normal = Ogre::StringConverter::parseVector3(ni->second);
	}

	if ((ni = retList.find("distance")) != retList.end())
	{
		object->m_Distance = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = retList.find("width")) != retList.end())
	{
		object->m_Width = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = retList.find("height")) != retList.end())
	{
		object->m_Height = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = retList.find("xsegments")) != retList.end())
	{
		object->m_xSegments = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = retList.find("ysegments")) != retList.end())
	{
		object->m_ySegments = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = retList.find("numcoordsets")) != retList.end())
	{
		object->m_NumCoordSets = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = retList.find("utile")) != retList.end())
	{
		object->m_uTile = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = retList.find("vtile")) != retList.end())
	{
		object->m_vTile = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = retList.find("hasnormals")) != retList.end())
	{
		object->m_HasNormals = Ogre::StringConverter::parseBool(ni->second);
	}

	Ogre::Entity *pEntity = object->CreatePlane();

	if ((ni = retList.find("shadows")) != retList.end())
	{
		pEntity->setCastShadows(Ogre::StringConverter::parseBool(ni->second));
	}

	if ((ni = retList.find("material")) != retList.end())
	{
		if(ni->second != "")
			;// pEntity->setMaterialName(ni->second);
	}

	retList = theList;
	return object;
}
//-----------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------
//----------CPLANEEDITORFACTORY--------------------------------------------------
//-------------------------------------------------------------------------------
CBaseEditor *CMirrorEditorFactory::CreateObject(CBaseEditor **parent, Ogre::NameValuePairList &params)
{
	Ogre::SceneNode* pNode;
	Ogre::Entity* pEntity;
	Ogre::String tail;
	Ogre::String objName = params["name"];

	Ogre::NameValuePairList::const_iterator ni;

	OgitorsRoot *ogRoot = OgitorsRoot::getSingletonPtr();
	mirrorEditor *object = new mirrorEditor();

	if ((ni = params.find("init")) != params.end())
	{
		tail = ogRoot->CreateUniqueID("Mirror","Node");
		objName = "Mirror" + tail;
	}

	Ogre::Vector3 vPos(0,0,0);
	Ogre::Quaternion qOrient = Ogre::Quaternion::IDENTITY;

	if ((ni = params.find("position")) != params.end())
	{
		// vPos = Ogre::StringConverter::parseVector3(ni->second);
	}

	if ((ni = params.find("orientation")) != params.end())
	{
		qOrient = Ogre::StringConverter::parseQuaternion(ni->second);
	}

	pNode = (*parent)->GetNode()->createChildSceneNode(objName,vPos,qOrient);

	if ((ni = params.find("normal")) != params.end())
	{
		object->m_Normal = Ogre::StringConverter::parseVector3(ni->second);
	}

	if ((ni = params.find("distance")) != params.end())
	{
		object->m_Distance = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = params.find("width")) != params.end())
	{
		object->m_Width = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = params.find("height")) != params.end())
	{
		object->m_Height = Ogre::StringConverter::parseReal(ni->second);
	}

	if ((ni = params.find("xsegments")) != params.end())
	{
		object->m_xSegments = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = params.find("ysegments")) != params.end())
	{
		object->m_ySegments = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = params.find("numcoordsets")) != params.end())
	{
		object->m_NumCoordSets = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = params.find("utile")) != params.end())
	{
		object->m_uTile = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = params.find("vtile")) != params.end())
	{
		object->m_vTile = Ogre::StringConverter::parseInt(ni->second);
	}

	if ((ni = params.find("hasnormals")) != params.end())
	{
		object->m_HasNormals = Ogre::StringConverter::parseBool(ni->second);
	}

	object->m_Name = objName;
	object->m_Handle = pNode;
	pEntity = object->CreatePlane();
	object->SetHandle(pEntity,false);

	if ((ni = params.find("shadows")) != params.end())
	{
		pEntity->setCastShadows(Ogre::StringConverter::parseBool(ni->second));
	}

	if ((ni = params.find("material")) != params.end())
	{
		if(ni->second != "")
			;// pEntity->setMaterialName(ni->second);
	}
	else
		;//pEntity->setMaterialName("BaseWhite");

	if ((ni = params.find("scale")) != params.end())
	{
		pNode->setScale(Ogre::StringConverter::parseVector3(ni->second));
	}

	if ((ni = params.find("autotracktarget")) != params.end())
	{
		object->m_AutoTrackTarget = ni->second;
	}

	if ((ni = params.find("locked")) != params.end())
	{
		object->SetLocked(Ogre::StringConverter::parseBool(ni->second), false);
	}

	m_InstanceCount++;
	return object;
}
//-------------------------------------------------------------------------------
